#include "rtsp.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include "stdio.h"

#define FIFO_NAME    "/tmp/H264_fifo"
#define BUFFERSIZE   PIPE_BUF

AWRtspStream::AWRtspStream(void):IVidRtsp(){

}

AWRtspStream::~AWRtspStream(void)
{

}

int32_t AWRtspStream::Start()
{
	if(access(FIFO_NAME,F_OK) == -1)
	{
		int32_t res = mkfifo(FIFO_NAME,0777);
		if(res != 0)
		{
			printf("[RTSPStream] Create fifo failed.\n");
			return false;
		}
	}
	return true;
}


int32_t AWRtspStream::Stop()
{

}

// 发送H264数据帧
int32_t AWRtspStream::Deliver(const uint8_t *data, int32_t size)
{
	if(data == NULL)
	{
		return 0;
	}
	// open pipe with non_block mode
	int32_t pipe_fd = open(FIFO_NAME, O_WRONLY | O_NONBLOCK);
	if(pipe_fd == -1)
	{
		return 0;
	}

	int32_t send_size = 0;
	int32_t remain_size = size;
	while(send_size < size)
	{
		int32_t data_len = (remain_size<BUFFERSIZE) ? remain_size : BUFFERSIZE;
		int32_t len = write(pipe_fd,data+send_size,data_len);
		if(len == -1)
		{
			static int32_t resend_conut = 0;
			if(errno == EAGAIN && ++resend_conut<=3)
			{
				printf("[RTSPStream] write fifo error,resend..\n");
				continue;
			}
			resend_conut = 0;
			printf("[RTSPStream] write fifo error,errorcode[%d],send_size[%d]\n",errno,send_size);
			break;
		}
		else
		{
			send_size+= len;
			remain_size-= len;
		}
	}
	close(pipe_fd);
	return 0;
}


int32_t aw_vid_rtsp_init( AW_VID_RTSP_HANDLE *handle ){
    vid_rtsp_ins *ins = new vid_rtsp_ins();

    ins->IVidRTSP = new AWRtspStream();
    printf( "IVidRend:%p\r\n", ins->IVidRTSP );
    if( ins->IVidRTSP == NULL ){
        return -1;
        printf( "get_instance failed...............\r\n" );
    }
    *handle = (AW_VID_RTSP_HANDLE)ins;
    return 0;
}

int32_t aw_vid_rtsp_deinit( /*in*/AW_VID_RTSP_HANDLE handle ){

    int32_t ret = 0;
    vid_rtsp_ins *ins = (vid_rtsp_ins*)handle;
    if( ins == NULL || ins->IVidRTSP == NULL ){
        printf( "%s param Error....\r\n", __FUNCTION__ );
        return -1;
    }
    delete ins->IVidRTSP;
    delete ins;
    return ret;
}

int32_t aw_vid_rtsp_start( /*in*/AW_VID_RTSP_HANDLE handle ){

    int32_t ret = 0;
    vid_rtsp_ins *ins = (vid_rtsp_ins*)handle;
    printf( "IVidRTSP:%p\r\n", ins->IVidRTSP );
    if( ins == NULL || ins->IVidRTSP == NULL ){
        printf( "%s param Error.................\r\n", __FUNCTION__ );
        return -1;
    }
    ret = ins->IVidRTSP->Start();
    if( ret < 0 ){
        printf( "aw_vid_rtsp_start failed\r\n" );
        return -1;
    }
    return ret;

}
int32_t aw_vid_rtsp_stop( /*in*/AW_VID_RTSP_HANDLE handle ){
    int32_t ret = 0;
    vid_rtsp_ins *ins = (vid_rtsp_ins*)handle;
    if( ins == NULL || ins->IVidRTSP == NULL ){
        printf( "%s param Error....\r\n", __FUNCTION__ );
        return -1;
    }
    ret = ins->IVidRTSP->Stop();
    if( ret < 0 ){
        printf( "aw_vid_rtsp_stop failed\r\n" );
        return -1;
    }
    return ret;


}

int32_t aw_vid_rtsp_deliver( /*in*/AW_VID_RTSP_HANDLE handle, uint8_t *data, int32_t size ){
    int32_t ret = 0;
    vid_rtsp_ins *ins = (vid_rtsp_ins*)handle;
    if( ins == NULL || ins->IVidRTSP == NULL ){
        printf( "%s param Error....\r\n", __FUNCTION__ );
        return -1;
    }
    ret = ins->IVidRTSP->Deliver(data, size);
    if( ret < 0 ){
        printf( "aw_vid_rtsp_deliver failed\r\n" );
        return -1;
    }
    return ret;
}
